#include "NextBIPHandle.h"
#include "PKB.h"

using namespace std;

NextBIPHandle::NextBIPHandle(void)
{
}

NextBIPHandle::~NextBIPHandle(void)
{
}
std::vector<std::vector<PROG_LINE>> NextBIPHandle::RetrieveNext(
        std::vector<PROG_LINE> prev_in, std::vector<PROG_LINE> next_in)
{
		std::sort(next_in.begin(), next_in.end());
        std::vector<std::vector<PROG_LINE>> result_vector;
        std::vector<PROG_LINE> next_out;
        std::vector<PROG_LINE> prev_out;
		std::set<PROG_LINE> temp;
		std::vector<PROG_LINE> found;
        unsigned int i;
		if(prev_in.size()==1)
		{
			PROG_LINE_ARRAY next_temp = PKB::nextbip.GetNextBIP(*prev_in.begin());
			for (auto it=next_temp.begin();it!=next_temp.end();it++)
			{
				PROG_LINE pl = *it;
				if (std::binary_search(next_in.begin(), next_in.end(), pl))
                        {
							    prev_out.push_back(*prev_in.begin());
                                next_out.push_back(pl);
                        }
			}
		}
		else if(next_in.size()==1)
		{
			PROG_LINE_ARRAY prev_temp = PKB::nextbip.GetPreviousBIP(*(next_in.begin()));
			for (auto it=prev_temp.begin();it!=prev_temp.end();it++)
			{
				PROG_LINE pl = *it;
				if (std::binary_search(prev_in.begin(), prev_in.end(), pl))
                        {
							    prev_out.push_back(pl);
                                next_out.push_back(*(next_in.begin()));
                        }
			}
		}
		else
		{
			for (i = 0; i < next_in.size(); i++)
			{
				PROG_LINE_ARRAY next_temp = PKB::nextbip.GetNextBIP(*prev_in.begin());
				for (auto it=next_temp.begin();it!=next_temp.end();it++)
				{
					PROG_LINE pl = *it;
					if (std::binary_search(next_in.begin(), next_in.end(), pl))
							{
									prev_out.push_back(*prev_in.begin());
									next_out.push_back(pl);
							}
				}
			}
		}
        result_vector.push_back(prev_out);
        result_vector.push_back(next_out);
		return result_vector;
}

std::vector<std::vector<PROG_LINE>> NextBIPHandle::RetrieveTransitiveNext(
	std::vector<PROG_LINE> prev_in, std::vector<PROG_LINE> next_in)
{
		std::sort(next_in.begin(), next_in.end());
        std::vector<std::vector<PROG_LINE>> result_vector;
        std::vector<PROG_LINE> next_out;
        std::vector<PROG_LINE> prev_out;

		std::set<PROG_LINE> temp;
		std::vector<PROG_LINE> found;
        unsigned int i;
        if(prev_in.size()==1)
		{
			PROG_LINE_ARRAY next_temp = PKB::nextbip.GetTransitiveNextBIP(*prev_in.begin());
			for (auto it=next_temp.begin();it!=next_temp.end();it++)
			{
				PROG_LINE pl = *it;
				if (std::binary_search(next_in.begin(), next_in.end(), pl))
                        {
							    prev_out.push_back(*prev_in.begin());
                                next_out.push_back(pl);
                        }
			}
		}
		else if(next_in.size()==1)
		{
			PROG_LINE_ARRAY prev_temp = PKB::nextbip.GetTransitivePreviousBIP(*next_in.begin());
			for (auto it=prev_temp.begin();it!=prev_temp.end();it++)
			{
				PROG_LINE pl = *it;
				if (std::binary_search(prev_in.begin(), prev_in.end(), pl))
                        {
							    prev_out.push_back(pl);
                                next_out.push_back(*next_in.begin());
                        }
			}
		}
		else{
			for (i = 0; i < prev_in.size(); i++)
			{
				PROG_LINE_ARRAY next_temp = PKB::nextbip.GetTransitiveNextBIP(prev_in[i]);
				for (auto it=next_temp.begin();it!=next_temp.end();it++)
				{
					PROG_LINE pl = *it;
					if (std::binary_search(next_in.begin(), next_in.end(), pl))
							{
									prev_out.push_back(prev_in[i]);
									next_out.push_back(pl);
							}
				}
			}
		}
        result_vector.push_back(prev_out);
        result_vector.push_back(next_out);
        
		return result_vector;
}